package com.example.studydemo.customview

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import com.example.studydemo.R
import kotlin.math.max

class FlowLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
    private var horizontalSpace = 0
    private var verticalSpace = 0

    init {
        context.theme.obtainStyledAttributes(attrs, R.styleable.FlowLayout, 0, 0).apply {
            try {
                //获取xml中的属性
                horizontalSpace =
                    this.getDimensionPixelSize(R.styleable.FlowLayout_horizontal_space, 0)
                verticalSpace = this.getDimensionPixelSize(R.styleable.FlowLayout_vertical_space, 0)
            } finally {
                recycle()
            }
        }
    }

    private val allLines = arrayListOf<List<View>>()//记录每一行有哪些View
    private val allLinesHeight = arrayListOf<Int>()//记录每一行的高度

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        allLines.clear()
        allLinesHeight.clear()

        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        var curLineWidth = 0
        var curLineHeight = 0
        var measureWidth = 0
        var measureHeight = 0

        var curLineViews = arrayListOf<View>()
        for (index in 0 until childCount) {
            val child = getChildAt(index)

            val childLayoutParams = child.layoutParams

            val childWidthMeasureSpec = getChildMeasureSpec(
                widthMeasureSpec,
                paddingLeft + paddingRight,
                childLayoutParams.width
            )
            val childHeightMeasureSpec = getChildMeasureSpec(
                heightMeasureSpec,
                paddingBottom + paddingTop,
                childLayoutParams.height
            )

            child.measure(childWidthMeasureSpec, childHeightMeasureSpec)

            if (curLineWidth + child.measuredWidth + horizontalSpace > widthSize) {
                //如果当前超出了布局宽度则换行
                measureWidth = max(measureWidth + horizontalSpace, curLineWidth)
                measureHeight += curLineHeight + verticalSpace
                allLines.add(curLineViews)
                allLinesHeight.add(curLineHeight)
                curLineViews = arrayListOf()
                curLineHeight = 0
                curLineWidth = 0
            }
            curLineViews.add(child)
            curLineWidth += child.measuredWidth + horizontalSpace
            //记录当前该行最大的高度作为该行高度
            curLineHeight = max(curLineHeight, child.measuredHeight)
        }

        allLines.add(curLineViews)
        allLinesHeight.add(curLineHeight)
        measureHeight += curLineHeight

        //layout本身也是一个子View需要根据父View模式来确定
        val realWidth =
            if (widthMode == MeasureSpec.EXACTLY) widthSize else measureWidth + paddingLeft + paddingTop
        val realHeight =
            if (heightMode == MeasureSpec.EXACTLY) heightSize else measureHeight + paddingTop + paddingBottom
        setMeasuredDimension(realWidth, realHeight)
    }

    override fun onLayout(p0: Boolean, p1: Int, p2: Int, p3: Int, p4: Int) {
        var curLeft = paddingLeft
        var curTop = paddingTop
        for ((index, line) in allLines.withIndex()) {
            line.forEach {
                //注意，这里使用的是measureWidth
                it.layout(
                    curLeft,
                    curTop,
                    curLeft + it.measuredWidth,
                    curTop + it.measuredHeight
                )
                curLeft += it.measuredWidth + horizontalSpace
            }
            curLeft = paddingLeft
            curTop += allLinesHeight[index] + verticalSpace
        }
    }
}